package com.example.generator.utils;


import com.example.generator.entity.FieldInfo;
import com.example.generator.entity.SelectCustomCondition;
import com.example.generator.entity.TableInfo;
import com.example.generator.entity.config.BaseInfoConfig;
import com.example.generator.entity.config.DataSourceConfig;
import com.example.generator.entity.config.TableConfig;
import com.example.generator.entity.vo.CodeParament;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * @author：QPX
 * @date：2024-01-26-11:24
 */
public class DataSourceUtil {
    private static Connection connection = null;
    private static PreparedStatement preparedStatement = null;

    private static final String SHOW_TABLE_MYSQL = "SHOW TABLE STATUS WHERE NAME=?;";
    private static final String SHOW_TABLE_POSTGRESQL = "SELECT obj_description(?::regclass, 'pg_class') AS Comment;";
    private static final String SHOW_TABLE_MYSQL_INFO = "SHOW FULL FIELDS  FROM";
    private static final String SHOW_TABLE_POSTGRESQL_INFO = "SELECT a.attname AS column_name, d.description AS column_description, format_type(a.atttypid, a.atttypmod) AS column_type\n" + "FROM pg_attribute AS a\n" + "LEFT JOIN pg_description AS d ON a.attrelid = d.objoid AND a.attnum = d.objsubid\n" + "WHERE a.attrelid = ?::regclass\n" + "AND a.attnum > 0\n" + "AND NOT a.attisdropped;";

    private static String jdbcType = null;


    public static void init(DataSourceConfig dataSourceConfig) throws Exception {
        Class.forName(dataSourceConfig.getDriver());
        connection = DriverManager.getConnection(dataSourceConfig.getUrl(), dataSourceConfig.getUserName(), dataSourceConfig.getPassword());
        if (dataSourceConfig.getDriver().contains("mysql")) {
            jdbcType = "MYSQL";
        } else if (dataSourceConfig.getDriver().contains("postgresql")) {
            jdbcType = "postgresql";
        }
    }

    public static TableInfo getTableRemark(CodeParament parament) throws Exception {
        TableConfig tableConfig = parament.getTableConfig();
        TableInfo tableInfo = new TableInfo();
        if (jdbcType.equals("MYSQL")) {
            preparedStatement = connection.prepareStatement(SHOW_TABLE_MYSQL);
        } else if (jdbcType.equals("postgresql")) {
            preparedStatement = connection.prepareStatement(SHOW_TABLE_POSTGRESQL);
        }
        preparedStatement.setString(1, tableConfig.getTableName());
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()) {
            tableInfo.setComment(resultSet.getString("Comment"));
        }
        return condition(tableInfo, parament);
    }

    public static List<FieldInfo> getField(TableConfig tableConfig) throws Exception {
        List<FieldInfo> fieldList = new ArrayList<>();
        ResultSet resultSet = null;
        if (jdbcType.equals("MYSQL")) {
            preparedStatement = connection.prepareStatement(SHOW_TABLE_MYSQL_INFO + " " + tableConfig.getTableName() + ";");
//            resultSet = preparedStatement.executeQuery(SHOW_TABLE_MYSQL_INFO + " " + tableConfig.getTableName() + ";");
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                FieldInfo fieldInfo = new FieldInfo();
                fieldInfo.setField(resultSet.getString("Field"));
                fieldInfo.setType(resultSet.getString("Type"));
                fieldInfo.setComment(resultSet.getString("Comment"));
                fieldInfo.setKey("PRI".equals(resultSet.getString("Key")));
                fieldList.add(fieldInfo);
            }
        } else if (jdbcType.equals("postgresql")) {
            preparedStatement = connection.prepareStatement(SHOW_TABLE_POSTGRESQL_INFO);
            preparedStatement.setString(1, tableConfig.getTableName());
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                FieldInfo fieldInfo = new FieldInfo();
                fieldInfo.setField(resultSet.getString("column_name"));
                fieldInfo.setType(resultSet.getString("column_type"));
                fieldInfo.setComment(resultSet.getString("column_description"));
                fieldList.add(fieldInfo);
            }
        }
        return fieldList;
    }

    private static TableInfo condition(TableInfo tableInfo, CodeParament parament) {
        TableConfig tableConfig = parament.getTableConfig();
        tableInfo.setName(tableConfig.getTableName());
        BaseInfoConfig baseInfoConfig = parament.getBaseInfoConfig();
        tableInfo.setTableFilterPrefix(tableConfig.getTableFilterPrefix());
        //设置作者
        tableInfo.setAuthor(baseInfoConfig.getAuthor());
        //是否使用注解
        tableInfo.setImportClass(baseInfoConfig.getImportClass());
        //mapper.xml路径
        if (parament.getBaseInfoConfig().getMapperXmlUrl() != null) {
            tableInfo.setMapperXmlUrl(baseInfoConfig.getMapperXmlUrl());
        }
        //是否生成selectPage方法
        tableInfo.setIsGeneratorSelect(baseInfoConfig.getIsGeneratorSelect());

        //是否生成save方法
        tableInfo.setIsGeneratorSave(baseInfoConfig.getIsGeneratorSave());
        //是否生成update方法
        tableInfo.setIsGeneratorUpdate(baseInfoConfig.getIsGeneratorUpdate());
        //是否生成删除方法
        tableInfo.setIsGeneratorDelete(baseInfoConfig.getIsGeneratorDelete());
        //是否逻辑删除
        tableInfo.setIsGeneratorDeleteL(baseInfoConfig.getIsGeneratorDeleteL());
        //是否生成自定义查询方法
        tableInfo.setIsSelectCustom(baseInfoConfig.getIsSelectCustom());
        if (tableInfo.getIsSelectCustom()) {
            List<SelectCustomCondition> selectCustomConditionList = parament.getSelectCustomConditionList();
            tableInfo.setSelectCustomConditionList(selectCustomConditionList);
            tableInfo.setSelectCustomWay(StringUtil.namingHump(selectCustomConditionList.get(0).getColumn()));
        }
        //自定义排序方法
        tableInfo.setOrderBy(parament.getOrderBy());
        //是否生成excel导入方法
        tableInfo.setIsGeneratorExcelImport(baseInfoConfig.getIsGeneratorExcelImport());
        //是否生成excel导出
        tableInfo.setIsGeneratorExcelDown(baseInfoConfig.getIsGeneratorExcelDown());
        if (baseInfoConfig.getIsGeneratorExcelDown()) {
            tableInfo.setSelectCustomConditionExcelList(parament.getSelectCustomConditionExcelList());
        }
        return tableInfo;
    }

}

